##
##  PassData.py
##
""" The PassData named tuple is the unit of currency in this system.
"""




#see <http://en.wikipedia.org/wiki/Drag_race#Basics_of_drag_racing>
##
## A 'Pass' is one run of a car.
## PassData holds info about the car that ran the Pass and the information
## collected from the RaceTrack during the Pass.
## With a PassData record, analysis and display are possible.
## New PassData records are created by a RaceTrack.do_a_pass(..)
## Old PassData records may be archived in a database.

from collections import namedtuple
import app.Database as Database
from app.Database import FieldDecl


## ###########################################################################
## ###########################################################################
## ###########################################################################


## DATA TYPE DECL

# here is the database name

passdata_table_name = 'PassData'

# here the fields we want

passdata_database = [
    FieldDecl( 'timestamp'  ,'REAL' ), # when this Record was created -- via datetime.datetime.now().timestamp()
    FieldDecl( 'driver_name','TEXT'      ),
    FieldDecl( 'car_name'   ,'TEXT'      ),
    FieldDecl( 'car_mass'   ,'REAL'      ), # stored in kg
    FieldDecl( 'description','TEXT'      ), # string -- arb text
    FieldDecl( 'track_name' ,'TEXT'      ), # string -- name of the RaceTrack the pass took place on
    FieldDecl( 'packet_event_list','PacketEventList' ) # string -- data collected by the RaceTrack's PacketSource
    ]

## define what a PassData is according to python
PassData = Database.make_namedtuple( passdata_table_name, passdata_database )

## define what PassData is according to sqlite3
Database.assure_table_exists( passdata_table_name, passdata_database )



## PacketEvent
PacketEvent = namedtuple( 'PacketEvent',
    [   'timestamp',   # float -- when it was recieved or when to send
        'packet'        # string -- data packet from pysical track
    ] )

## list of PacketEvent and functions to interface with database
## this struct is needed in order to give sqlite3 a specific type name to work on
## and that type name is 'PacketEventList'
PacketEventList = namedtuple( 'PacketEventList',
    'pel' # just a list of PacketEvents
    )

# python to sqlite3
def PacketEventList_adapter(pel) :
    """ given pel -- a PacketEventList
        returns a byte string for storage into sqlite3
        so use .encode('ascii')
    """
    return str(pel).encode('ascii')


# sqlite3 to python
def PacketEventList_converter(bs) :
    """ given bs -- a byte string
            so prefix partition with b
            and use .decode on the results
        return a PacketEventList
    """
    assert( bs.startswith(b'PacketEventList') )
    return eval(bs) ## DANGEROUS !!


# here is the additional transformer dictionary to use
passdata_transformer_dictionary = {
    'PacketEventList' : (PacketEventList,PacketEventList_adapter,PacketEventList_converter)
   }

## register the adaptor/converters
Database.attach_transformers( passdata_database, passdata_transformer_dictionary )





## ###########################################################################
## ###########################################################################
## ###########################################################################

## API


def Store(pd) :
    """ Store a PassData record pd to the database.
    """
    return Database.store_to_table(passdata_table_name, pd )

def Fetch(timestamp,*filter) :
    """ Fetches a PassData record from the  database.
        Return None if nothing was found.
    """
    fetched = Database.get_recent_timestamp(
        passdata_table_name,
        passdata_database,
        timestamp,*filter)

    #print(fetched)

    if fetched is not None :
        fetched = PassData(*fetched)

    return fetched






def dump() :
    """ don't do this at home
    """
    return Database.dump_table(passdata_table_name)
